"""
Dummy backend
Use as reference

This file is part of polyglot, etc.
"""

import datetime
from backends.support import Backend, Course, AssignmentGrade, CategoryGrade, ResourceCategory, ResourceRawHTML, Task, FileUpload, Quiz, MultipartQuestion, MultipleChoiceQuestion, FreeResponseQuestion, Forum, Post

class DummyQuiz(Quiz):
    def __init__(self, course, id, name):
        super().__init__(id, name)
        self.course = course

    # Fetch quiz questions
    # This should be call carefully, as it has nasty side effects in some courses!
    # Hence why it is a method, breaking with the usual @property technique.

    def questions(self):
        question1 = MultipleChoiceQuestion("Is mathematics fun?", ["Absolutely!", "Definitely!"])
        question2A = FreeResponseQuestion("What's your favourite part?")
        question2B = FreeResponseQuestion("Why?")
        question2 = MultipartQuestion([question2A, question2B])

        return [question1, question2]

    # Submit quiz where responses is the output of questions filled out
    # True on success

    def submit(self, responses):
        return True

class DummyForum(Forum):
    def __init__(self, course, id, name):
        super().__init__(id, name)
        self.course = course

    # Existing discussion posts.
    # Returns a root Post object (with many nested replies, perhaps).

    @property
    def thread(self):
        reply2 = Post("Babs Seed", "That gives me a good idea to annoy the CMCs!", [])
        reply1 = Post("Jane Doe", "DNA nanotechnology involves forming artificial, designed nanostructures", [reply2])
        question = Post("Carl Smith", "In the homework problem set, you looked at a formula to estimate the number of basepairs in a DNA strand given the length. What are your thoughts?", [reply1])
        return question

    # Parent is the post to be replied to, body is the text
    # Usual return code

    def reply(self, parent, body):
        return True

class DummyCourse(Course):
    def __init__(self, data):
        # Course ID unique within this backend but not necessarily in general
        self.id = data["id"]

        # Course name and teacher name, no localisation?
        self.title = data["title"]
        self.teacher = data["teacher"]

        # Single course grade, if that's available (otherwise, it's computed)
        self.grade_summary = data["grade"]

    # Detailed gradebook, including weighted categories

    @property
    def grades(self):
        # Uh-oh, let's make a request to the server
        # Request the grade break down for course id self.id
        # Then fill out like this

        grade1 = AssignmentGrade("Chapter 1 Test", 0.95)
        grade2 = AssignmentGrade("Homework 1", 0.95)

        category1 = CategoryGrade("Tests", 0.80, [grade1])
        category2 = CategoryGrade("Homeworks", 0.20, [grade2])

        return [category1, category2]

    # Arbitrary hierarchy of resources
    # Lectures, external links, the syllabus, etc should go here.
    # This is necessary as many (most? all?) LMSes support course-specific WYSIWYG editing
    # That said, use sparingly as it is not semantic (compare tasks, etc)

    @property
    def resources(self):
        rsrc1 = ResourceRawHTML("Notes", "<p>To-do: Should this be refactored more?</p>")
        rsrc2 = FileUpload("foobarbaz", "Essay")
        rsrc3 = DummyQuiz(self, "foobazbar", "Post-essay quiz")
        rsrc4 = DummyForum(self, "bazbar", "Post-quiz discussion")
        rsrc5 = ResourceRawHTML("Syllabus", "1. Be good")
        cat = ResourceCategory("Week 1", [], [rsrc1, rsrc2, rsrc3, rsrc4])
        cat2 = ResourceCategory("Modules", [cat], [])
        return ResourceCategory("Root", [cat2], [rsrc5])

    # Tasks are assignments with a definite (near) due-date.
    # Naturally suited to traditional courses (where tonight's homework is here)
    # Probably not of much use to self-paced classes

    @property
    def tasks(self):
        t = Task("Homework 2", datetime.datetime.now() + datetime.timedelta(days=1))
        t.resources = [ResourceRawHTML("Details", "Poke poke!")]
        return [t]

    # Upload a file where ID was passed in a FileUpload model
    # Returns true if the upload was successful and false otherwise

    def upload_file(self, id, file):
        return True

class DummyBackend(Backend):
    # Parameters needed for authentication
    Config = ["Username", "Password"]

    # Attempts login based on config from Config
    # Return True on success and False on failure.
    # Caller is responsible for tracking authentication statement based on this response.

    def login(self, config):
        print("Incurring expensive authentication...")

        if not (config["Username"] == "AzureDiamond" and config["Password"] == "hunter2"):
            return False

        self.session_id = "cookies_are_tasty"
        return True

    # List of courses available (available post-auth)
    # Array of Course objects, although in practice this will be inherited

    @property
    def courses(self):
        # Fetch something with self.session_id

        course = DummyCourse({
            "id": "ABC123",
            "title": "Algebra II",
            "teacher": "Carl Smith",
            "grade": 0.95
        })

        return [course]
